package com.tools.common.security.secret;

import com.tools.common.io.CharsetEnum;
import com.tools.common.object.Note;

/**
 * SM4 对称加密算法的管理实例
 * */
@Note("SM4 对称加密算法的管理实例")
public final class SM4Cypher implements Cypher {

    @Note("对称密钥")
    private final String key;

    @Note("默认字符集")
    private final CharsetEnum charset;

    /* **************************************************************************************
     *
     *          构造器
     *
     * **************************************************************************************
     * */

    public SM4Cypher() {
        this.key = SecretKit.createSM4Key();
        this.charset = CharsetEnum.UTF_8;
    }

    public SM4Cypher(CharsetEnum charset) {
        private_checkCharsetEnum(charset);
        this.key = SecretKit.createSM4Key();
        this.charset = charset;
    }

    public SM4Cypher(String key) {
        private_checkSM4KeyLength(key);
        this.key = key;
        this.charset = CharsetEnum.UTF_8;
    }


    public SM4Cypher(String key, CharsetEnum charset) {
        private_checkSM4KeyLength(key);
        private_checkCharsetEnum(charset);
        this.key = key;
        this.charset = charset;
    }

    public String getKey() {
        return key;
    }

    public CharsetEnum getCharset() {
        return charset;
    }

    /* **************************************************************************************
     *
     *          实现方法
     *
     * **************************************************************************************
     * */

    @Override
    public String encrypt(String plaintext) {
        return SecretKit.encryptWithSM4(plaintext, this.key, this.charset);
    }

    @Override
    public String decrypt(String ciphertext) {
        return SecretKit.decryptWithSM4(ciphertext, this.key, this.charset);
    }

    @Override
    public String encrypt(String plaintext, CharsetEnum charset) {
        return SecretKit.encryptWithSM4(plaintext, this.key, charset);
    }

    @Override
    public String decrypt(String ciphertext, CharsetEnum charset) {
        return SecretKit.decryptWithSM4(ciphertext, this.key, charset);
    }

    /* **************************************************************************************
     *
     *          私有逻辑
     *
     * **************************************************************************************
     * */

    @Note("校验密钥")
    private void private_checkSM4KeyLength(String key) {
        if(key == null) throw new NullPointerException("SM4 的密钥为 null");
        if(key.length() != 32) {
            throw new IllegalArgumentException("SM4 的密钥用字符串来表示必须要 32 个纯 16 进制的字符串");
        }
    }

    @Note("校验字符集枚举")
    private void private_checkCharsetEnum(CharsetEnum charset) {
        if(charset == null) throw new NullPointerException("字符集枚举为 null");
    }
}
